package com.sservice.common;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 一个用户 相同url 同时提交 相同数据 验证
 * 主要通过 session中保存到的url 和 请求参数。如果和上次相同，则是重复提交表单
 *
 * @author Administrator
 */
public class SameUrlDataInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            SameUrlData annotation = method.getAnnotation(SameUrlData.class);
            if (annotation != null) {
                if (repeatDataValidator(request))//如果重复相同数据
                    return false;
                else
                    return true;
            }
            return true;
        } else {
            return super.preHandle(request, response, handler);
        }
    }

    /**
     * 验证同一个url数据是否相同提交  ,相同返回true
     *
     * @param httpServletRequest
     * @return
     */
    public boolean repeatDataValidator(HttpServletRequest httpServletRequest) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();

        String params = mapper.writeValueAsString(httpServletRequest.getParameterMap());
        String url = httpServletRequest.getRequestURI();
        Map<String, String> map = new HashMap<String, String>();

        map.put(url, params);
        String nowUrlParams = map.toString();//

        Object preUrlParams = httpServletRequest.getSession().getAttribute("repeatData");

//        Integer.valueOf(requestTime)
        if (preUrlParams == null)//如果上一个数据为null,表示还没有访问页面
        {
            httpServletRequest.getSession().setAttribute("repeatData", nowUrlParams);
            httpServletRequest.getSession().setAttribute("requestTime", String.valueOf(new Date().getTime()));
            return false;
        } else//否则，已经访问过页面
        {
            Object requestTime = httpServletRequest.getSession().getAttribute("requestTime");
            Long timeStamp = Long.valueOf(requestTime.toString());
            if (preUrlParams.toString().equals(nowUrlParams) && (((new Date().getTime()) - timeStamp) < 2000))//如果上次url+数据和本次url+数据相同，并且请求时间间隔小于2S 则认为表单二次提交
            {
                return true;
            } else//如果上次 url+数据 和本次url加数据不同，则不是重复提交
            {
                httpServletRequest.getSession().setAttribute("repeatData", nowUrlParams);
                httpServletRequest.getSession().setAttribute("requestTime", String.valueOf(new Date().getTime())); // 记录当前请求时间
                return false;
            }

        }
    }

}